Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / frontend / RNodeTransports.test.js

Displaying Raw • Download


tests/frontend/RNodeTransports.test.js 3f7ef731b5effd9aa3a81eceea66fd6c2b56498c (3f7ef731) Text, 8.14 KB

Tff7b72import Tb4b4b4{ Te6edf3describeTb4b4b4, Te6edf3itTb4b4b4, Te6edf3expectTb4b4b4, Te6edf3vi Tb4b4b4} Tff7b72from Ta5d6ff"vitest"Tb4b4b4;
Tff7b72import Te6edf3SerialTransport Tff7b72from Ta5d6ff"@/js/rnode/transports/SerialTransport.js"Tb4b4b4;
Tff7b72import Te6edf3BluetoothTransportTb4b4b4, Tb4b4b4{
Te6edf3NUS_SERVICE_UUIDTb4b4b4,
Te6edf3NUS_RX_CHARACTERISTIC_UUIDTb4b4b4,
Te6edf3NUS_TX_CHARACTERISTIC_UUIDTb4b4b4,
Tb4b4b4} Tff7b72from Ta5d6ff"@/js/rnode/transports/BluetoothTransport.js"Tb4b4b4;
Tff7b72import Te6edf3WifiTransport Tff7b72from Ta5d6ff"@/js/rnode/transports/WifiTransport.js"Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"SerialTransport.request"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"throws WEB_SERIAL_UNAVAILABLE when navigator.serial is missing"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3env Tff7b72= Tb4b4b4{ Te6edf3navigatorTff7b72: Tb4b4b4{Tb4b4b4} Tb4b4b4}Tb4b4b4;
Tff7b72await Te6edf3expectTb4b4b4(Te6edf3SerialTransportTb4b4b4.Te6edf3requestTb4b4b4(Tb4b4b4{ Te6edf3env Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3rejectsTb4b4b4.Te6edf3toMatchObjectTb4b4b4(Tb4b4b4{
Te6edf3codeTff7b72: Ta5d6ff"WEB_SERIAL_UNAVAILABLE"Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"translates NotFoundError to NO_PORT_SELECTED"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3env Tff7b72= Tb4b4b4{
Te6edf3navigatorTff7b72: Tb4b4b4{
Te6edf3serialTff7b72: Tb4b4b4{
Te6edf3requestPortTff7b72: Te6edf3vi
Tb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3mockRejectedValueTb4b4b4(
Tffa657ObjectTb4b4b4.Te6edf3assignTb4b4b4(Tff7b72new Tf85149ErrorTb4b4b4(Ta5d6ff"No port selected by the user."Tb4b4b4)Tb4b4b4, Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"NotFoundError" Tb4b4b4}Tb4b4b4)
Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tff7b72await Te6edf3expectTb4b4b4(Te6edf3SerialTransportTb4b4b4.Te6edf3requestTb4b4b4(Tb4b4b4{ Te6edf3env Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3rejectsTb4b4b4.Te6edf3toMatchObjectTb4b4b4(Tb4b4b4{
Te6edf3codeTff7b72: Ta5d6ff"NO_PORT_SELECTED"Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"returns a wrapped transport reporting capabilities"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3fakePort Tff7b72= Tb4b4b4{ Te6edf3openTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3closeTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3readableTff7b72: Tb4b4b4{Tb4b4b4}Tb4b4b4, Te6edf3writableTff7b72: Tb4b4b4{Tb4b4b4} Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3env Tff7b72= Tb4b4b4{
Te6edf3navigatorTff7b72: Tb4b4b4{ Te6edf3serialTff7b72: Tb4b4b4{ Te6edf3requestPortTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Te6edf3fakePortTb4b4b4) Tb4b4b4} Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3transport Tff7b72= Tff7b72await Te6edf3SerialTransportTb4b4b4.Te6edf3requestTb4b4b4(Tb4b4b4{ Te6edf3env Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4)Tb4b4b4.Te6edf3toBeInstanceOfTb4b4b4(Te6edf3SerialTransportTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3canFlashEsp32Tb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3canFlashNrf52Tb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3canManageDeviceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3descriptionTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"serial"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"flags polyfilled when navigator.serial is the polyfill module"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3fakePort Tff7b72= Tb4b4b4{ Te6edf3openTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3polyfill Tff7b72= Tb4b4b4{ Te6edf3requestPortTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Te6edf3fakePortTb4b4b4) Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3env Tff7b72= Tb4b4b4{
Te6edf3navigatorTff7b72: Tb4b4b4{ Te6edf3serialTff7b72: Te6edf3polyfill Tb4b4b4}Tb4b4b4,
Te6edf3serialTff7b72: Te6edf3polyfillTb4b4b4,
Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3transport Tff7b72= Tff7b72await Te6edf3SerialTransportTb4b4b4.Te6edf3requestTb4b4b4(Tb4b4b4{ Te6edf3env Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3polyfilledTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3descriptionTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"serial-polyfill"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"forwards baudRate to underlying port.open"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3fakePort Tff7b72= Tb4b4b4{
Te6edf3openTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tff7b72undefinedTb4b4b4)Tb4b4b4,
Te6edf3closeTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tff7b72undefinedTb4b4b4)Tb4b4b4,
Te6edf3readableTff7b72: Tb4b4b4{ Te6edf3_rTff7b72: T79c0ff1 Tb4b4b4}Tb4b4b4,
Te6edf3writableTff7b72: Tb4b4b4{ Te6edf3_wTff7b72: T79c0ff1 Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3transport Tff7b72= Tff7b72new Te6edf3SerialTransportTb4b4b4(Te6edf3fakePortTb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3transportTb4b4b4.Te6edf3openTb4b4b4(Tb4b4b4{ Te6edf3baudRateTff7b72: T79c0ff921600 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3fakePortTb4b4b4.Te6edf3openTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(Tb4b4b4{ Te6edf3baudRateTff7b72: T79c0ff921600 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3readableTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3fakePortTb4b4b4.Te6edf3readableTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3writableTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3fakePortTb4b4b4.Te6edf3writableTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"BluetoothTransport.request"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"throws WEB_BLUETOOTH_UNAVAILABLE when missing"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72await Te6edf3expectTb4b4b4(Te6edf3BluetoothTransportTb4b4b4.Te6edf3requestTb4b4b4(Tb4b4b4{ Te6edf3envTff7b72: Tb4b4b4{ Te6edf3navigatorTff7b72: Tb4b4b4{Tb4b4b4} Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3rejectsTb4b4b4.Te6edf3toMatchObjectTb4b4b4(Tb4b4b4{
Te6edf3codeTff7b72: Ta5d6ff"WEB_BLUETOOTH_UNAVAILABLE"Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"translates NotFoundError to NO_DEVICE_SELECTED"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3env Tff7b72= Tb4b4b4{
Te6edf3navigatorTff7b72: Tb4b4b4{
Te6edf3bluetoothTff7b72: Tb4b4b4{
Te6edf3requestDeviceTff7b72: Te6edf3vi
Tb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3mockRejectedValueTb4b4b4(Tffa657ObjectTb4b4b4.Te6edf3assignTb4b4b4(Tff7b72new Tf85149ErrorTb4b4b4(Ta5d6ff"User cancelled"Tb4b4b4)Tb4b4b4, Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"NotFoundError" Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tff7b72await Te6edf3expectTb4b4b4(Te6edf3BluetoothTransportTb4b4b4.Te6edf3requestTb4b4b4(Tb4b4b4{ Te6edf3env Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3rejectsTb4b4b4.Te6edf3toMatchObjectTb4b4b4(Tb4b4b4{
Te6edf3codeTff7b72: Ta5d6ff"NO_DEVICE_SELECTED"Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"uses NUS UUID filters by default"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3requestDevice Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tb4b4b4{Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3env Tff7b72= Tb4b4b4{ Te6edf3navigatorTff7b72: Tb4b4b4{ Te6edf3bluetoothTff7b72: Tb4b4b4{ Te6edf3requestDevice Tb4b4b4} Tb4b4b4} Tb4b4b4}Tb4b4b4;
Tff7b72await Te6edf3BluetoothTransportTb4b4b4.Te6edf3requestTb4b4b4(Tb4b4b4{ Te6edf3env Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3args Tff7b72= Te6edf3requestDeviceTb4b4b4.Te6edf3mockTb4b4b4.Te6edf3callsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3argsTb4b4b4.Te6edf3filtersTb4b4b4)Tb4b4b4.Te6edf3toEqualTb4b4b4(Tb4b4b4[Tb4b4b4{ Te6edf3servicesTff7b72: Tb4b4b4[Te6edf3NUS_SERVICE_UUIDTb4b4b4] Tb4b4b4}Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3argsTb4b4b4.Te6edf3optionalServicesTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Te6edf3NUS_SERVICE_UUIDTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"exposes the standard NUS UUIDs"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3NUS_SERVICE_UUIDTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"6e400001-b5a3-f393-e0a9-e50e24dcca9e"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3NUS_RX_CHARACTERISTIC_UUIDTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"6e400002-b5a3-f393-e0a9-e50e24dcca9e"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3NUS_TX_CHARACTERISTIC_UUIDTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"6e400003-b5a3-f393-e0a9-e50e24dcca9e"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"WifiTransport"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"validates IPv4 hosts"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3WifiTransportTb4b4b4.Te6edf3isValidHostTb4b4b4(Ta5d6ff"192.168.1.50"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3WifiTransportTb4b4b4.Te6edf3isValidHostTb4b4b4(Ta5d6ff"10.0.0.1"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3WifiTransportTb4b4b4.Te6edf3isValidHostTb4b4b4(Ta5d6ff"not a host"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3WifiTransportTb4b4b4.Te6edf3isValidHostTb4b4b4(Ta5d6ff"bad_host_with_underscore"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3WifiTransportTb4b4b4.Te6edf3isValidHostTb4b4b4(Ta5d6ff""Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3WifiTransportTb4b4b4.Te6edf3isValidHostTb4b4b4(Tff7b72undefinedTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"validates hostnames"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3WifiTransportTb4b4b4.Te6edf3isValidHostTb4b4b4(Ta5d6ff"rnode.local"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3WifiTransportTb4b4b4.Te6edf3isValidHostTb4b4b4(Ta5d6ff"rnode"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"throws INVALID_HOST when constructed with an invalid host"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tff7b72new Te6edf3WifiTransportTb4b4b4(Ta5d6ff"???"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toThrowErrorTb4b4b4(Ta5d6ff/invalid_host/Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"only supports OTA flashing"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3t Tff7b72= Tff7b72new Te6edf3WifiTransportTb4b4b4(Ta5d6ff"192.168.1.50"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3tTb4b4b4.Te6edf3canOtaFlashTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3tTb4b4b4.Te6edf3canFlashEsp32Tb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3tTb4b4b4.Te6edf3canManageDeviceTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3tTb4b4b4.Te6edf3descriptionTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"wifi://192.168.1.50"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"upload posts firmware via XMLHttpRequest with progress"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3xhrInstances Tff7b72= Tb4b4b4[Tb4b4b4]Tb4b4b4;
Tff7b72function Te6edf3FakeXhrTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3xhrInstancesTb4b4b4.Te6edf3pushTb4b4b4(Tff7b72thisTb4b4b4)Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3upload Tff7b72= Tb4b4b4{Tb4b4b4}Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3open Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3send Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3status Tff7b72= T79c0ff200Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3responseText Tff7b72= Ta5d6ff"ok"Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3uploadTb4b4b4.Te6edf3onprogressTff7b72?Tb4b4b4.Tb4b4b4(Tb4b4b4{ Te6edf3lengthComputableTff7b72: Tff7b72trueTb4b4b4, Te6edf3loadedTff7b72: T79c0ff50Tb4b4b4, Te6edf3totalTff7b72: T79c0ff100 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3uploadTb4b4b4.Te6edf3onprogressTff7b72?Tb4b4b4.Tb4b4b4(Tb4b4b4{ Te6edf3lengthComputableTff7b72: Tff7b72trueTb4b4b4, Te6edf3loadedTff7b72: T79c0ff100Tb4b4b4, Te6edf3totalTff7b72: T79c0ff100 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3onloadTff7b72?Tb4b4b4.Tb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72function Te6edf3FakeFormDataTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3entries Tff7b72= Tb4b4b4[Tb4b4b4]Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3append Tff7b72= Tb4b4b4(Te6edf3kTb4b4b4, Te6edf3vTb4b4b4, Te6edf3nTb4b4b4) Tb4b4b4=> Tff7b72thisTb4b4b4.Te6edf3entriesTb4b4b4.Te6edf3pushTb4b4b4(Tb4b4b4{ Te6edf3kTb4b4b4, Te6edf3vTb4b4b4, Te6edf3n Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3env Tff7b72= Tb4b4b4{ Te6edf3XMLHttpRequestTff7b72: Te6edf3FakeXhrTb4b4b4, Te6edf3FormDataTff7b72: Te6edf3FakeFormData Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3t Tff7b72= Tff7b72new Te6edf3WifiTransportTb4b4b4(Ta5d6ff"192.168.1.50"Tb4b4b4, Tb4b4b4{ Te6edf3envTb4b4b4, Te6edf3timeoutMsTff7b72: T79c0ff1000 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3progress Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3blob Tff7b72= Tb4b4b4{ Te6edf3sizeTff7b72: T79c0ff100 Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Tff7b72await Te6edf3tTb4b4b4.Te6edf3uploadTb4b4b4(Te6edf3blobTb4b4b4, Te6edf3progressTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4.Te6edf3statusTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff200Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3progressTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(T79c0ff50Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3progressTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(T79c0ff100Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3xhrInstancesTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4.Te6edf3openTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(Ta5d6ff"POST"Tb4b4b4, Ta5d6ff"http://192.168.1.50/update"Tb4b4b4, Tff7b72trueTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"upload rejects with HTTP_ERROR on non-2xx"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72function Te6edf3FakeXhrTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3upload Tff7b72= Tb4b4b4{Tb4b4b4}Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3open Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3send Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3status Tff7b72= T79c0ff500Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3responseText Tff7b72= Ta5d6ff"boom"Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3onloadTff7b72?Tb4b4b4.Tb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72function Te6edf3FakeFormDataTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3append Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3t Tff7b72= Tff7b72new Te6edf3WifiTransportTb4b4b4(Ta5d6ff"192.168.1.50"Tb4b4b4, Tb4b4b4{ Te6edf3envTff7b72: Tb4b4b4{ Te6edf3XMLHttpRequestTff7b72: Te6edf3FakeXhrTb4b4b4, Te6edf3FormDataTff7b72: Te6edf3FakeFormData Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3expectTb4b4b4(Te6edf3tTb4b4b4.Te6edf3uploadTb4b4b4(Tb4b4b4{Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3rejectsTb4b4b4.Te6edf3toMatchObjectTb4b4b4(Tb4b4b4{ Te6edf3codeTff7b72: Ta5d6ff"HTTP_ERROR"Tb4b4b4, Te6edf3statusTff7b72: T79c0ff500 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"upload rejects with UPLOAD_TIMEOUT on ontimeout"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72function Te6edf3FakeXhrTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3upload Tff7b72= Tb4b4b4{Tb4b4b4}Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3open Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72thisTb4b4b4.Te6edf3send Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tff7b72thisTb4b4b4.Te6edf3ontimeoutTff7b72?Tb4b4b4.Tb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72function Te6edf3FakeFormDataTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72thisTb4b4b4.Te6edf3append Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3t Tff7b72= Tff7b72new Te6edf3WifiTransportTb4b4b4(Ta5d6ff"192.168.1.50"Tb4b4b4, Tb4b4b4{ Te6edf3envTff7b72: Tb4b4b4{ Te6edf3XMLHttpRequestTff7b72: Te6edf3FakeXhrTb4b4b4, Te6edf3FormDataTff7b72: Te6edf3FakeFormData Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3expectTb4b4b4(Te6edf3tTb4b4b4.Te6edf3uploadTb4b4b4(Tb4b4b4{Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3rejectsTb4b4b4.Te6edf3toMatchObjectTb4b4b4(Tb4b4b4{ Te6edf3codeTff7b72: Ta5d6ff"UPLOAD_TIMEOUT" Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────